<template>
  <div class="courseSection">
    <div class="header">
      <el-page-header @back="$router.push({ name: 'courses' })" :content="courseName"></el-page-header>
      <el-button type="primary" size="small" @click="addSection">+添加阶段</el-button>
    </div>
    <el-card>
      <!-- 通过自定义节点内容的  scoped slot 来进行布局 -->
      <!--
        allow-drop:
          拖拽时判定目标节点能否被放置。
          type 参数有三种情况：'prev'、'inner' 和 'next'，
          分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
        expand-on-click-node:
          是否在点击节点的时候展开或者收缩节点， 默认值为 true，
          如果为 false，则只有点箭头图标的时候才会展开或者收缩节点。
        node-drop:
          拖拽成功完成时触发的事件
      -->
      <el-tree
        v-loading="isLoading"
        :data="section"
        :props="defaultProps"
        draggable
        :allow-drop="handleAllowDrop"
        :expand-on-click-node="false"
        @node-drop="handleNodeDrop">
        <!-- 自定义节点内容 -->
        <div class="inner" slot-scope="{ node, data }">
          <span>{{node.label}}</span>
          <!-- 章节部分 根据条件显示合适的button按钮-->
          <span v-if="data.sectionName">
            <el-button size="small" @click="sectionEdit(data)">编辑</el-button>
            <el-button size="small" @click="addCourse(data)">添加课时</el-button>
            <el-button size="small" @click="changeSectionType(data)">{{data.status | statusFilter }}</el-button>
          </span>
          <!-- 课时部分 -->
          <span v-else>
            <el-button size="small" @click="courseEdit(data)">编辑</el-button>
            <el-button size="small" @click="addCourseVideo(data)">上传视频</el-button>
            <el-button size="small" @click="changeCourseType(data)">{{data.status | statusFilter}}</el-button>
          </span>
        </div>
      </el-tree>
    </el-card>
    <section-info ref="section" :courseId="courseId" @refresh="getSectionsRefresh"></section-info>
    <courses-info ref="course" :courseId="courseId" @refresh="getSectionsRefresh"></courses-info>
    <show-or-hide ref="showOrHide" @refresh="getSectionsRefresh"></show-or-hide>
  </div>
</template>

<script>
import { getSectionAndLesson, saveOrUpdateSection, saveOrUpdateLesson } from '@/services/course-sections'
import bus from '@/assets/js/busEvent'
// 引入章节弹窗
import sectionInfo from './components/sectionInfo'
// 引入课时弹窗
import coursesInfo from './components/courseInfo'
// 引入显示或隐藏
import ShowOrHide from './components/showOrHide'
export default {
  name: 'courseSection',
  props: {
    courseId: {
      type: [String, Number]
    }
  },
  components: {
    sectionInfo,
    coursesInfo,
    ShowOrHide
  },
  data () {
    return {
      courseName: '',
      // 存储当前课时的所有信息
      section: [],
      // 描述节点的相关信息
      defaultProps: {
        // 当前子节点存储的位置,是基于section里面的数据找到lessonDTOS
        children: 'lessonDTOS',
        // label 标签名
        // 因为章节名为sectionName, 而课时名为theme,
        // 因为父节点和子节点名称不同,
        // 所以通过将label设置函数,
        // 来进行内部判断,如果是有存在当前的任一名称,就在页面中渲染出来
        label: function (data) {
          return data.sectionName || data.theme
        }
      },
      isLoading: false
    }
  },
  created () {
    this.getSectionAndLesson()
  },
  mounted () {
    this.courseName = this.$route.query.courseName
    bus.$on('getTheme', val => {
      bus.theme = val
    })
  },
  filters: {
    statusFilter (val) {
      if (val === 0) {
        return '已隐藏'
      } else if (val === 1) {
        return '待更新'
      } else {
        return '已更新'
      }
    }
  },
  methods: {
    // 获取章节和课程信息
    async getSectionAndLesson () {
      const { data } = await getSectionAndLesson({ courseId: this.courseId })
      if (data.code === '000000') {
        this.section = data.data
      }
    },
    // 设置节点是否能被移动
    handleAllowDrop (draggingNode, dropNode, type) {
      // 移动的条件满足:
      // 1.必须是同级移动
      // 2.限制将章节移动到课时前后,也不能将章节的课时移动到其他章节
      // 因为在本次项目中,所有的课时都具有 sectionId, 所以通过该属性来确定如何移动(被移动的节点,和移动到的节点必须拥有同一个sectionId才能移动 )
      return type !== 'inner' && draggingNode.data.sectionId === dropNode.data.sectionId
    },
    // 拖拽完成后触发的事件
    async handleNodeDrop (draggingNode, dropNode, type, event) {
      this.isLoading = true
      try {
        // promise.all() 解决异步批量请求,当请求的数据过多时,会造成同步的形式
        // 得到拖拽后所有的同级数据
        // console.log(dropNode.parent.childNodes)
        await Promise.all(dropNode.parent.childNodes.map((item, index) => {
          // 对章节和课时改变顺序时,做出不同的数据请求(根据两者的不同点做出判断依据)
          if (draggingNode.data.lessonDTOS) {
            // 正在拖拽的数据是章节
            return saveOrUpdateSection({
              id: item.data.id,
              orderNum: index
            })
          } else {
            // 课时操作
            return saveOrUpdateLesson({
              id: item.data.id,
              orderNum: index
            })
          }
        }))
        this.$message.success('数据更新成功')
      } catch (err) {
        this.$message.error('数据更新失败')
      }
      this.isLoading = false
    },
    addSection () {
      this.$refs.section.dialogOpen()
    },
    getSectionsRefresh () {
      this.getSectionAndLesson()
    },
    // 编辑章节
    sectionEdit (data) {
      this.$refs.section.sectionsEditOpen(data)
    },
    // 添加课时
    addCourse (data) {
      this.$refs.course.courseAdd(data)
    },
    // 编辑课时
    courseEdit (data) {
      this.$refs.course.courseEdit(data)
    },
    // 改变章节显示或隐藏
    changeSectionType (data) {
      this.$refs.showOrHide.changeSection(data)
    },
    // 改变课时的显示与隐藏
    changeCourseType (data) {
      this.$refs.showOrHide.changeCourse(data)
    },
    // 上传视频
    addCourseVideo (data) {
      this.$router.push({
        name: 'courseVideo',
        params: {
          courseId: data.courseId,
          lessonId: data.id
        }
      })
      bus.$emit('getTheme', data.theme)
    }
  }
}
</script>

<style lang="scss" scoped>
.header{
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}
.el-page-header {
  margin-bottom: 20px;
}
.el-card{
  height: 100vh;
}
.el-tree{
height: 100%;
::v-deep .el-tree-node__content{
  height: auto;
}
.inner{
  padding: 6px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex: 1;
  border-bottom: 1px solid #ebeef5;
}
}

</style>
